﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Data;
using Home.Haushalt.Lib;
using Infragistics.Win;
using Infragistics.Win.UltraWinGrid;
using Home.Haushalt.Lib.Element;

namespace Home.Haushalt.Lib
{
    /// <summary>
    /// 
    /// </summary>
    public class _MonthbalanceController
    {
        /// <summary>Wird auch für das Errechnen des restlichen Saldo in dem MonthbalanceGrid genutzt</summary>
        public static SortedList<string, _MonthbalanceController> Balances = new SortedList<string, _MonthbalanceController>();

        /// <summary>Wird für das Errechnen des restlichen Saldo in dem MonthbalanceGrid genutzt</summary>
        public double CalculateScheduledSaldoTempField = 0;

        /// <summary></summary>
        private DateTime _from;

        /// <summary></summary>
        public DateTime BalanceFrom { get { return _from; } }

        /// <summary></summary>
        private DateTime _to;

        /// <summary></summary>
        public DateTime BalanceTo { get { return _to; } }

        /// <summary></summary>
        private string _termin;

        /// <summary></summary>
        private double _startSaldo = 0;

        /// <summary></summary>
        public double StartSaldo { get { return _startSaldo; } set { _startSaldo = value; } }

        /// <summary></summary>
        public double EndSaldo { get { return CalculateScheduledSaldoTempField; } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        public _MonthbalanceController(int year, int month)
        {
            int dayInMonth = DateTime.DaysInMonth(year, month);

            _from = new DateTime(year, month, 1);
            _to = new DateTime(year, month, dayInMonth);

            _termin = year.ToString() + month.ToString("00");

            if (_termin.Equals(DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString("00")))
            //Wenn aktueller Monat
            {
                _startSaldo = DAO.GetCurrentSaldo();
            }
            else
            //Weitere Monate
            {
                this._startSaldo = _MonthbalanceController.Balances.Last().Value.CalculateScheduledSaldoTempField;
            }

            //UpdateStartSaldo();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>Saldo</returns>
        public double UpdateStartSaldo()
        {
            if (_termin.Equals(DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString("00")))
            //Wenn aktueller Monat
            {
                _startSaldo = DAO.GetCurrentSaldo();
            }
            else if (_MonthbalanceController.Balances.IndexOfValue(this) > 0)
            {
                _MonthbalanceController preBalance = _MonthbalanceController.Balances.ElementAt(_MonthbalanceController.Balances.IndexOfValue(this) - 1).Value;

                this._startSaldo = preBalance.CalculateScheduledSaldoTempField;

                //DateTime nextTermin = DateTime.Now.AddMonths(1);

                //if ((nextTermin.Year.ToString() + nextTermin.Month.ToString("00")) == _termin)
                //{
                //    MonthbalanceController bindedBalance = MonthbalanceController.Balances[currentTermin];
                //    _startSaldo = bindedBalance.EndSaldo;
                //}
            }

            return _startSaldo;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="day"></param>
        /// <returns></returns>
        private DateTime AdaptToMonth(int year, int month, int day)
        {
            int maxDayInMonth = DateTime.DaysInMonth(year, month);
            if (day > maxDayInMonth)
                day = maxDayInMonth;
            return new DateTime(year, month, day);
        }

        /// <summary>
        /// 
        /// </summary>
        public void DataBind()
        {
            CalculateScheduledSaldoTempField = _startSaldo;

            //Eventuelle Termin-Buchungen löschen
            DataRow[] rows = DAO.Tables[Date.ElementType].Select(string.Format("{0} = '{1}' and {2} = -1", Date.Fields.Termin, _termin, Date.Fields.Id));
            for (int i = 0; i < rows.Length; i++)
            {
                rows[i].Delete();
            }

            //Termin-Buchungen hinzufügen
            DataSet ds = new DataSet();
            ds.Tables.Add(DAO.Tables[Posten.ElementType].Copy());
            ds.Tables.Add(DAO.Tables[Postengroup.ElementType].Copy());

            DataRelation postenHasPostengroup = new DataRelation("postenHasPostengroup",
                ds.Tables[Postengroup.ElementType.Name].Columns[Postengroup.Fields.Id],
                ds.Tables[Posten.ElementType.Name].Columns[Posten.Fields.PostengruppeId]
            );
            ds.Relations.Add(postenHasPostengroup);

            foreach (DataRow row in ds.Tables[Postengroup.ElementType.Name].Select(Postengroup.Fields.Turnus + " = true"))
            {
                foreach (DataRow turnusRow in row.GetChildRows(postenHasPostengroup))
                {
                    int day = turnusRow[Posten.Fields.DateDay].ToInt();

                    DateTime postenFrom = turnusRow[Posten.Fields.DateFrom].ToDateTime();
                    if (day > postenFrom.Day)
                    {
                        postenFrom = AdaptToMonth(postenFrom.Year, postenFrom.Month, day);
                    }

                    DateTime postenTo = (turnusRow[Posten.Fields.DateTo] != DBNull.Value) ? turnusRow[Posten.Fields.DateTo].ToDateTime() : DateTime.MaxValue;
                    if (day < postenTo.Day)
                    {
                        postenTo = AdaptToMonth(postenTo.Year, postenTo.Month, day);
                    }

                    //Zeitrahmen prüfen (ist richtig so)
                    if (postenFrom <= _to && postenTo >= _to)
                    {
                        //Turnus-Monat prüfen
                        if (new List<string>(turnusRow.ToString(Posten.Fields.Turnus).Split(DAO.ARRAYSPLITER_IN_XMLATTRIBUT)).Contains(_from.Month.ToString()))
                        {
                            //Ob Buchung noch nicht gespeichert ist
                            string statement = string.Format("{0} = {1} and {2} = {3} and {4} = '{5}'",
                                Date.Fields.PostenId, turnusRow.ToInt(Posten.Fields.Id), Date.Fields.IsFree, false,
                                Date.Fields.Termin, _termin);

                            if (DAO.Tables[Date.ElementType].Select(statement).Length == 0)
                            {
                                DataRow dateRow = DAO.Tables[Date.ElementType].NewRow();
                                dateRow[Date.Fields.Active] = true;
                                dateRow[Date.Fields.GroupId] = turnusRow[Posten.Fields.GroupId];
                                dateRow[Date.Fields.IsFree] = false;
                                dateRow[Date.Fields.Name] = turnusRow[Posten.Fields.Name];
                                dateRow[Date.Fields.OpponentId] = turnusRow[Posten.Fields.OpponentId];
                                dateRow[Date.Fields.PostenId] = turnusRow[Posten.Fields.Id];
                                dateRow[Date.Fields.Posting] = AdaptToMonth(_from.Year, _from.Month, day);
                                dateRow[Date.Fields.SaldotypId] = turnusRow[Posten.Fields.SaldotypeId];
                                dateRow[Date.Fields.Summe] = turnusRow[Posten.Fields.Summe];
                                dateRow[Date.Fields.Termin] = _termin;
                                dateRow[Date.Fields.TerminTag] = turnusRow[Posten.Fields.DateDay];
                                DAO.Tables[Date.ElementType].Rows.Add(dateRow);
                            }
                        }
                    }
                }
            }
        }
    }
}
